document.addEventListener("DOMContentLoaded", () => {
  const gridDisplay = document.querySelector(".grid")
  const scoreDisplay = document.getElementById("score")
  const resultDisplay = document.getElementById("result")
  const width = 4
  let squares = []
  let score = 0

  //创建游戏面板
  function createBoard() {
    for (let i = 0; i < width * width; i++) {
      let square = document.createElement("div")
      square.innerHTML = 0
      square.className = "color0"
      gridDisplay.appendChild(square)
      squares.push(square)
    }
    generate()
    generate()
  }
  createBoard()

  //在空的格中随机生成一个数
  function generate() {
    checkForColor()
    let randomNumber = Math.floor(Math.random() * squares.length)
    if (squares[randomNumber].innerHTML == 0) {
      squares[randomNumber].innerHTML = 2
      squares[randomNumber].className = "color2"
    } else {
      generate()
    }
    checkForGameOver()
  }

  //右滑
  function moveRight() {
    for (let i = 0; i < width * width; i++) {
      if (i % 4 == 0) {
        let totalOne = squares[i].innerHTML
        let totalTwo = squares[i + 1].innerHTML
        let totalThree = squares[i + 2].innerHTML
        let totalFour = squares[i + 3].innerHTML
        let row = [
          parseInt(totalOne),
          parseInt(totalTwo),
          parseInt(totalThree),
          parseInt(totalFour),
        ]

        let filteredRow = row.filter((num) => num)
        let missing = width - filteredRow.length
        let zeros = Array(missing).fill(0)
        let newRow = zeros.concat(filteredRow)

        squares[i].innerHTML = newRow[0]
        squares[i + 1].innerHTML = newRow[1]
        squares[i + 2].innerHTML = newRow[2]
        squares[i + 3].innerHTML = newRow[3]
      }
    }
  }

  //左滑
  function moveLeft() {
    for (let i = 0; i < width * width; i++) {
      if (i % 4 == 0) {
        let totalOne = squares[i].innerHTML
        let totalTwo = squares[i + 1].innerHTML
        let totalThree = squares[i + 2].innerHTML
        let totalFour = squares[i + 3].innerHTML
        let row = [
          parseInt(totalOne),
          parseInt(totalTwo),
          parseInt(totalThree),
          parseInt(totalFour),
        ]

        let filteredRow = row.filter((num) => num)
        let missing = width - filteredRow.length
        let zeros = Array(missing).fill(0)
        let newRow = filteredRow.concat(zeros)

        squares[i].innerHTML = newRow[0]
        squares[i + 1].innerHTML = newRow[1]
        squares[i + 2].innerHTML = newRow[2]
        squares[i + 3].innerHTML = newRow[3]
      }
    }
  }

  //下滑
  function moveDown() {
    for (let i = 0; i < width; i++) {
      let totalOne = squares[i].innerHTML
      let totalTwo = squares[i + width].innerHTML
      let totalThree = squares[i + width * 2].innerHTML
      let totalFour = squares[i + width * 3].innerHTML
      let column = [
        parseInt(totalOne),
        parseInt(totalTwo),
        parseInt(totalThree),
        parseInt(totalFour),
      ]

      let filteredColumn = column.filter((num) => num)
      let missing = width - filteredColumn.length
      let zeros = Array(missing).fill(0)
      let newColumn = zeros.concat(filteredColumn)

      squares[i].innerHTML = newColumn[0]
      squares[i + width].innerHTML = newColumn[1]
      squares[i + width * 2].innerHTML = newColumn[2]
      squares[i + width * 3].innerHTML = newColumn[3]
    }
  }

  //上滑
  function moveUp() {
    for (let i = 0; i < width; i++) {
      let totalOne = squares[i].innerHTML
      let totalTwo = squares[i + width].innerHTML
      let totalThree = squares[i + width * 2].innerHTML
      let totalFour = squares[i + width * 3].innerHTML
      let column = [
        parseInt(totalOne),
        parseInt(totalTwo),
        parseInt(totalThree),
        parseInt(totalFour),
      ]

      let filteredColumn = column.filter((num) => num)
      let missing = width - filteredColumn.length
      let zeros = Array(missing).fill(0)
      let newColumn = filteredColumn.concat(zeros)

      squares[i].innerHTML = newColumn[0]
      squares[i + width].innerHTML = newColumn[1]
      squares[i + width * 2].innerHTML = newColumn[2]
      squares[i + width * 3].innerHTML = newColumn[3]
    }
  }

  //合并行相邻相同的数值
  function combineRow() {
    for (let i = 0; i < width * width - 1; i++) {
      if (squares[i].innerHTML === squares[i + 1].innerHTML) {
        let combinedTotal =
          parseInt(squares[i].innerHTML) + parseInt(squares[i + 1].innerHTML)
        squares[i].innerHTML = combinedTotal
        squares[i + 1].innerHTML = 0
        score += combinedTotal
        scoreDisplay.innerHTML = score
      }
    }
    checkForWin()
    checkForColor()
  }

  //合并列相邻相同的数值
  function combineColumn() {
    for (let i = 0; i < width * (width - 1); i++) {
      if (squares[i].innerHTML === squares[i + width].innerHTML) {
        let combinedTotal =
          parseInt(squares[i].innerHTML) +
          parseInt(squares[i + width].innerHTML)
        squares[i].innerHTML = combinedTotal
        squares[i + width].innerHTML = 0
        score += combinedTotal
        scoreDisplay.innerHTML = score
      }
    }
    checkForWin()
    checkForColor()
  }

  //指定键盘
  function control(e) {
    if (e.keyCode === 39) {
      keyRight()
    } else if (e.keyCode === 37) {
      keyLeft()
    } else if (e.keyCode === 40) {
      keyDown()
    } else if (e.keyCode === 38) {
      keyUp()
    }
  }

  document.addEventListener("keyup", control)

  function keyRight() {
    moveRight()
    combineRow()
    moveRight()
    generate()
  }
  function keyLeft() {
    moveLeft()
    combineRow()
    moveLeft()
    generate()
  }
  function keyDown() {
    moveDown()
    combineColumn()
    moveDown()
    generate()
  }
  function keyUp() {
    moveUp()
    combineColumn()
    moveUp()
    generate()
  }

  //检查是否出现2048
  function checkForWin() {
    for (let i = 0; i < squares.length; i++) {
      if (squares[i].innerHTML === "2048") {
        resultDisplay.innerHTML = "You win!"
        document.removeEventListener("keyup", control)
      }
    }
  }

  //判断格子颜色
  function checkForColor() {
    let gridNow = document.querySelector(".grid")
    for (let i = 0; i < width * width; i++) {
      let c = parseInt(squares[i].innerHTML)
      switch (c) {
        case 0:
          squares[i].className = "color0"
          break
        case 2:
          squares[i].className = "color2"
          break
        case 4:
          squares[i].className = "color4"
          break
        case 8:
          squares[i].className = "color8"
          break
        case 16:
          squares[i].className = "color16"
          break
        case 32:
          squares[i].className = "color32"
          break
        case 64:
          squares[i].className = "color64"
          break
        case 128:
          squares[i].className = "color128"
          break
        case 256:
          squares[i].className = "color256"
          break
        case 512:
          squares[i].className = "color512"
          break
        case 1024:
          squares[i].className = "color1024"
          break
        case 2048:
          squares[i].className = "color2048"
          break
      }
    }
  }

  //检查是否没有空白格且相邻格子无法合并
  function checkForGameOver() {
    let zero = 0
    for (let i = 0; i < squares.length; i++) {
      if (squares[i].innerHTML === "0") {
        zero++
      }
    }
    for (let i = 0; i < width * width - 1; i++) {
      if (squares[i].innerHTML === squares[i + 1].innerHTML) {
        zero++
      }
    }
    for (let i = 0; i < width * (width - 1); i++)
      if (squares[i].innerHTML === squares[i + width].innerHTML) {
        zero++
      }
    if (zero === 0) {
      resultDisplay.innerHTML = "You lose!"
      document.removeEventListener("keyup", control)
    }
  }
})
